package com.xinggq.common.context;

import java.util.UUID;

/**
 * 链路追踪上下文工具类
 * 使用ThreadLocal存储当前线程的追踪ID，用于分布式链路追踪
 *
 * @author system
 * @since 2025/1/10
 */
public final class TraceContext {

    /**
     * InheritableThreadLocal存储追踪ID，支持跨线程传递
     */
    private static final InheritableThreadLocal<String> TRACE_ID_HOLDER = new InheritableThreadLocal<>();

    /**
     * 追踪ID请求头名称
     */
    public static final String TRACE_ID_HEADER = "X-Trace-Id";

    /**
     * 追踪ID前缀
     */
    private static final String TRACE_ID_PREFIX = "trace-";

    /**
     * 私有构造方法，防止实例化
     */
    private TraceContext() {
        throw new UnsupportedOperationException("工具类不允许实例化");
    }

    /**
     * 生成新的追踪ID
     *
     * @return 追踪ID
     */
    public static String generateTraceId() {
        return TRACE_ID_PREFIX + UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 设置当前线程的追踪ID
     *
     * @param traceId 追踪ID
     */
    public static void setTraceId(String traceId) {
        TRACE_ID_HOLDER.set(traceId);
    }

    /**
     * 获取当前线程的追踪ID
     *
     * @return 追踪ID，如果未设置则返回null
     */
    public static String getTraceId() {
        return TRACE_ID_HOLDER.get();
    }

    /**
     * 获取当前线程的追踪ID，如果未设置则生成新的
     *
     * @return 追踪ID
     */
    public static String getOrGenerateTraceId() {
        String traceId = TRACE_ID_HOLDER.get();
        if (traceId == null || traceId.trim().isEmpty()) {
            traceId = generateTraceId();
            TRACE_ID_HOLDER.set(traceId);
        }
        return traceId;
    }

    /**
     * 清除当前线程的追踪ID
     * 建议在请求结束时调用，避免内存泄漏
     */
    public static void clear() {
        TRACE_ID_HOLDER.remove();
    }

    /**
     * 检查当前线程是否设置了追踪ID
     *
     * @return 如果设置了追踪ID返回true，否则返回false
     */
    public static boolean hasTraceId() {
        String traceId = TRACE_ID_HOLDER.get();
        return traceId != null && !traceId.trim().isEmpty();
    }
}